home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9110.ZIP / EMBEDCP.ASC < prev    next >
Text File  |  1991-09-10  |  6KB  |  203 lines

  1. _C++ FOR EMBEDDED SYSTEMS_
  2. by Stuart G. Phillips and Kevin J. Rowett
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7. // MIOTDREM
  8. // --------
  9. // Copyright (c) 1991, Stuart G. Phillips.  All rights reserved.
  10. // Permission is granted for non-commercial use of this software.
  11. // You are expressly prohibited from selling this software in any form,
  12. // distributing it with another product, or removing this notice.
  13. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14. // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15. // WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  16. // PURPOSE.
  17. // This module contains the main() for the MIO version of TDREMOTE.  The
  18. // module is primarily responsible for initialization; TDREMOTE functions
  19. // are handled in other modules.
  20.  
  21. #include "mio.h"
  22. #include "8530.h"
  23. #include "miotdr.h"
  24.  
  25. #ifdef SERIAL_DEBUG
  26.  
  27. // Communication region used to deposit status information about the
  28. // programs progress etc in the shared memory window.
  29.  
  30. struct comm_region {    unsigned short status;
  31.                         unsigned short scc_status;
  32.                         unsigned short scc_special;
  33.                         unsigned short int_cnt;
  34.                         unsigned short rx_cnt;
  35.                         unsigned short tx_cnt;
  36.                         unsigned char  command;
  37.                    };
  38. #endif
  39.  
  40. struct relo_creg {      unsigned short offset;
  41.                         unsigned short segment;
  42.                         unsigned short count;
  43.                         unsigned char command;
  44.                  };
  45.  
  46. // Command values for RELO.LOD
  47. #define RELO_NULL       0x00
  48. #define RELO_COPYTO     0x01
  49. #define RELO_COPYFROM   0x02
  50. #define RELO_EXIT       0x03
  51.  
  52. // Magic number signifying presence of "RELO" support
  53. #define RELO_MAGIC      0x5a41
  54.  
  55. extern void tdr_processor();
  56. static void relo_lod();
  57.  
  58. #ifdef SERIAL_DEBUG
  59. static struct comm_region *creg = (struct comm_region *)0x80;
  60. #endif
  61.  
  62. // Globals
  63.  
  64. unsigned char rx_buffer[BUFLEN],
  65.               tx_buffer[BUFLEN];
  66.  
  67. unsigned _stklen = 512U;
  68.  
  69. void main()
  70. {
  71.     unsigned char data,val;
  72.     unsigned short i;
  73.  
  74.     disable();
  75.  
  76.     // Enable ICU in the V40 peripheral select register
  77.     data = inportb(OPSEL);
  78.     outportb(OPSEL,data|ICU);
  79.     data = inportb(OPSEL);
  80.  
  81. #ifdef SERIAL_DEBUG
  82.     creg->status = data;
  83. #endif
  84.  
  85.     /* Initialize the ICU */
  86.  
  87.     outportb(IULA,ICUBASE);                     // set base address */
  88.     outportb(IMDW,IIW1|IIW4NR|IEM|IET);         // no IIW4, extended mode,
  89.                                                 // edge triggered
  90.                                                 //
  91.     outportb(IMKW,IVEC);                        // Set vector base for PIC/
  92.     outportb(IMKW,SI7);                         // IRQ7 is slave
  93.  
  94.     outportb(IMKW,0xff);                        // Mask off all interrupts
  95.     relo_lod();                                 // Provide relocation support
  96.                                                 // to MIOLOAD
  97. #ifdef SERIAL_DEBUG
  98.     creg->status = 0;
  99.     creg->scc_status = 0;
  100.     creg->scc_special = 0;
  101.     creg->int_cnt = 0;
  102.     creg->rx_cnt = 0;
  103.     creg->tx_cnt = 0;
  104.     creg->command = 0xff;
  105. #endif
  106.  
  107.     comm_init();
  108.  
  109.     tdr_processor();
  110.     /*NOTREACHED*/
  111. }
  112.  
  113. static void relo_lod()
  114. {
  115.     struct relo_creg *creg = (struct relo_creg *) 0x80;
  116.     unsigned short *magic = (unsigned short *) 0x88;
  117.     unsigned char *go = (unsigned char *) 0x9f;
  118.     unsigned char *swin, *p;
  119.     unsigned short i, relo_done = 0;
  120.  
  121.     // Initialize command field in communication region
  122.     creg->command = 0xff;
  123.  
  124.     // Implant magic number so that MIOLOAD knows we're up and running
  125.     *magic = RELO_MAGIC;
  126.  
  127.     while (!relo_done){
  128.         // Wait for command value to change from 0xff
  129.         while (creg->command == 0xff) ;
  130.         switch(creg->command){
  131.             case RELO_COPYTO:
  132.                 p = (unsigned char *)(((long)creg->segment << 16) +
  133.                                        (long)creg->offset);
  134.                 swin = (unsigned char *) 0x100;
  135.                 for(i = creg->count; i != 0; i--)
  136.                     *p++ = *swin++;
  137.                 creg->command = 0xff;
  138.                 break;
  139.             case RELO_COPYFROM:
  140.                 p = (unsigned char *)(((long)creg->segment << 16) +
  141.                                        (long)creg->offset);
  142.                 swin = (unsigned char *) 0x100;
  143.                 for(i = creg->count; i != 0; i--)
  144.                     *swin++ = *p++;
  145.                 creg->command = 0xff;
  146.                 break;
  147.             case RELO_EXIT:
  148.                 creg->command = 0xff;
  149.                 relo_done = 1;
  150.                 break;
  151.             default:
  152.                 creg->command = 0xff;
  153.                 break;
  154.         }
  155.     }
  156.     // Clear our magic marker and then reset go flag to 0xf4 (halt) code. 
  157.     // Wait for MIOLOAD to set this to 0x90 to indicate we should continue.
  158.     *magic = 0;
  159.     *go = 0xf4;
  160.  
  161.     while (*go != 0x90) ;
  162. }
  163.  
  164.  
  165.  
  166.  
  167. Figure 1: Format of EXE file header
  168.  
  169. struct EXEHDR { 
  170.     unsigned short magic;       // EXE file if 0x5a4d
  171.     unsigned short nbytes;      // Size of last page in bytes
  172.     unsigned short npages;      // Size of image in pages
  173.                         // 1 page = 512 bytes
  174.     unsigned short nreloc;      // Number of relocation items
  175.     unsigned short hdrsize;     // Size of EXE header
  176.     unsigned short endmin;      // Minimum memory
  177.     unsigned short hilo_flag;
  178.     unsigned short ss_offset;   // Stack segment offset
  179.     unsigned short val_sp;      // Initial value for SP
  180.     unsigned short chksum;  
  181.     unsigned short val_ip;      // Initial value for IP
  182.     unsigned short cs_offset;   // Code segment offset
  183.     unsigned short rel_offset;  // Offset of relocation items
  184.     unsigned short ovl_num;     // Overlay number
  185. };
  186.  
  187.  
  188.  
  189.  
  190. Figure 2: Format of LOD file header
  191.  
  192.  
  193. struct LODHDR {
  194.     unsigned short magic;       // LOD file if 0x4655
  195.     unsigned short version;     // Version id of LOD header
  196.     unsigned short val_offset;  // Initial value for IP
  197.     unsigned short val_seg;     // initial value for CS
  198.     long           timestamp;   // DOS time stamp of orig. EXE file
  199.     long           image_size;  // Image size in bytes
  200. };
  201.  
  202.  
  203.